package com.accelstack.cmp.service;

import com.accelstack.cmp.entity.Rack;
import com.accelstack.cmp.entity.Server;
import com.accelstack.cmp.repository.RackRepository;
import com.accelstack.cmp.repository.ServerRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 机架Service
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class RackService {
    
    private final RackRepository rackRepository;
    private final ServerRepository serverRepository;
    
    @Transactional
    public Rack create(Rack rack) {
        return rackRepository.save(rack);
    }
    
    @Transactional
    public Rack update(Rack rack) {
        return rackRepository.save(rack);
    }
    
    @Transactional
    public void deleteById(Long id) {
        rackRepository.deleteById(id);
    }
    
    public Optional<Rack> findById(Long id) {
        return rackRepository.findById(id);
    }
    
    public List<Rack> findAll() {
        return rackRepository.findAll();
    }
    
    public Page<Rack> findAll(Pageable pageable) {
        return rackRepository.findAll(pageable);
    }
    
    public List<Rack> findByDatacenterId(Long datacenterId) {
        return rackRepository.findByDatacenterId(datacenterId);
    }
    
    /**
     * 批量创建机架
     */
    @Transactional
    public List<Rack> batchCreate(List<Rack> racks) {
        return rackRepository.saveAll(racks);
    }
    
    /**
     * 批量删除机架
     */
    @Transactional
    public void batchDelete(List<Long> ids) {
        rackRepository.deleteAllById(ids);
    }
    
    /**
     * 获取机架使用率
     */
    public Map<String, Object> getUtilization(Long rackId) {
        Map<String, Object> result = new HashMap<>();
        
        Optional<Rack> rackOpt = rackRepository.findById(rackId);
        if (rackOpt.isEmpty()) {
            return result;
        }
        
        Rack rack = rackOpt.get();
        Integer totalUnits = rack.getUHeight() != null ? rack.getUHeight() : 42; // 默认42U
        
        // 获取该机架中的所有服务器
        List<Server> servers = serverRepository.findByRackId(rackId);
        
        // 计算已使用的U位（假设每台服务器占用1U或2U，这里需要根据实际情况调整）
        int usedUnits = servers.size(); // 简化计算，实际应该从Server实体中获取uHeight字段
        
        double utilizationRate = totalUnits > 0 ? (double) usedUnits / totalUnits * 100 : 0;
        
        result.put("rackId", rackId);
        result.put("rackName", rack.getName());
        result.put("totalUnits", totalUnits);
        result.put("usedUnits", usedUnits);
        result.put("availableUnits", totalUnits - usedUnits);
        result.put("utilizationRate", String.format("%.2f%%", utilizationRate));
        result.put("serverCount", servers.size());
        
        return result;
    }
    
    /**
     * 获取机架可用U位
     */
    public Map<String, Object> getAvailableUnits(Long rackId) {
        Map<String, Object> result = new HashMap<>();
        
        Optional<Rack> rackOpt = rackRepository.findById(rackId);
        if (rackOpt.isEmpty()) {
            return result;
        }
        
        Rack rack = rackOpt.get();
        Integer totalUnits = rack.getUHeight() != null ? rack.getUHeight() : 42;
        
        // 获取该机架中的所有服务器
        List<Server> servers = serverRepository.findByRackId(rackId);
        
        // 获取已占用的U位（简化处理）
        Set<Integer> occupiedUnits = new HashSet<>();
        for (int i = 0; i < servers.size() && i < totalUnits; i++) {
            occupiedUnits.add(i + 1);
        }
        
        // 计算可用U位
        List<Integer> availableUnits = new ArrayList<>();
        for (int i = 1; i <= totalUnits; i++) {
            if (!occupiedUnits.contains(i)) {
                availableUnits.add(i);
            }
        }
        
        result.put("rackId", rackId);
        result.put("rackName", rack.getName());
        result.put("totalUnits", totalUnits);
        result.put("availableUnits", availableUnits);
        result.put("availableCount", availableUnits.size());
        result.put("occupiedCount", occupiedUnits.size());
        
        return result;
    }
    
    /**
     * 获取机架中的所有服务器
     */
    public List<Server> getServersByRackId(Long rackId) {
        return serverRepository.findByRackId(rackId);
    }
}

